namespace SilverSea.Sockets
{
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

    public class WebServer
    {
        public static Hashtable CurrentFrames = new Hashtable();
        private int int_0;
        private int int_1 = 0xc350;
        private ManualResetEvent manualResetEvent_0;
        private static Socket socket_0;
        private string string_0 = "127.0.0.1";
        private TcpListener tcpListener_0;
        private Thread thread_0;

        public event ClientRequestCurrentImageHandler ClientRequestCurrentImage;

        public event ClientSendPTZCommandHandler ClientSendPTZCommand;

        public event SocketErrorEventHandler SocketErrorEvent;

        private void method_0()
        {
            this.thread_0 = null;
            this.manualResetEvent_0.Close();
            this.manualResetEvent_0 = null;
        }

        public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket _socket)
        {
            string s = (((string.Empty + sHttpVersion + sStatusCode + "\r\n") + "Server: cx1193719-b\r\n") + "Content-Type: " + sMIMEHeader + "\r\n") + "Accept-Ranges: bytes\r\n";
            s = string.Concat(new object[] { s, "Content-Length: ", iTotBytes, "\r\n\r\n" });
            byte[] bytes = Encoding.ASCII.GetBytes(s);
            this.SendToBrowser(bytes, ref _socket);
        }

        public void SendToBrowser(byte[] bSendData, ref Socket _socket)
        {
            try
            {
                if ((socket_0.Connected && (_socket.Send(bSendData, bSendData.Length, SocketFlags.None) == -1)) && (this.SocketErrorEvent != null))
                {
                    this.SocketErrorEvent("Socket Error cannot Send Packet");
                }
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while send data to browser: " + exception.Message);
                }
            }
        }

        public void SendToBrowser(string sData, ref Socket _socket)
        {
            this.SendToBrowser(Encoding.ASCII.GetBytes(sData), ref _socket);
        }

        public void SignalToStop()
        {
            if (this.tcpListener_0 != null)
            {
                this.tcpListener_0.Stop();
                this.tcpListener_0 = null;
            }
            if (socket_0 != null)
            {
                try
                {
                    socket_0.Shutdown(SocketShutdown.Both);
                    socket_0.Close();
                    socket_0 = null;
                }
                catch (Exception exception)
                {
                    if (this.SocketErrorEvent != null)
                    {
                        this.SocketErrorEvent("Error while shutdown socket: " + exception.Message);
                    }
                }
            }
            if (this.thread_0 != null)
            {
                this.manualResetEvent_0.Set();
            }
        }

        public void Start()
        {
            try
            {
                this.tcpListener_0 = new TcpListener(IPAddress.Any, this.int_1);
                this.tcpListener_0.Start();
                if (this.thread_0 != null)
                {
                    while (this.thread_0.ThreadState == ThreadState.AbortRequested)
                    {
                        Application.DoEvents();
                    }
                }
                this.manualResetEvent_0 = new ManualResetEvent(false);
                this.thread_0 = new Thread(new ThreadStart(this.WorkerThread));
                this.thread_0.Start();
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while start web server: " + exception.Message);
                }
            }
        }

        public void Stop()
        {
            if (this.Running)
            {
                this.thread_0.Abort();
                this.WaitForStop();
            }
        }

        public bool ThumbnailCallback()
        {
            return false;
        }

        public void WaitForStop()
        {
            if (this.thread_0 != null)
            {
                this.thread_0.Join();
                this.method_0();
            }
        }

        public void WorkerThread()
        {
            while (!this.manualResetEvent_0.WaitOne(0, true))
            {
                if (this.tcpListener_0 == null)
                {
                    break;
                }
                try
                {
                    socket_0 = this.tcpListener_0.AcceptSocket();
                    if (socket_0.Connected)
                    {
                        try
                        {
                            byte[] buffer = new byte[0x400];
                            socket_0.Receive(buffer, buffer.Length, SocketFlags.None);
                            string str2 = Encoding.ASCII.GetString(buffer);
                            if (str2.Substring(0, 3) != "GET")
                            {
                                throw new Exception("Only GET method is supported.");
                            }
                            int index = str2.IndexOf("HTTP", 1);
                            string sHttpVersion = str2.Substring(index, 8);
                            string str = str2.Substring(0, index - 1);
                            index = str.IndexOf("=") + 1;
                            string s = str.Substring(index);
                            string ptzCommand = string.Empty;
                            if (s.IndexOf("&") != -1)
                            {
                                if (s.Contains("move="))
                                {
                                    string str6 = s.Substring(s.IndexOf("&") + 1);
                                    if (str6.IndexOf("&") != -1)
                                    {
                                        str6 = str6.Substring(0, str6.IndexOf("&"));
                                    }
                                    ptzCommand = str6.Substring(str6.IndexOf("=") + 1);
                                }
                                s = s.Substring(0, s.IndexOf("&"));
                            }
                            if (s == "list")
                            {
                                string sData = string.Empty;
                                for (int i = 0; i < this.int_0; i++)
                                {
                                    object obj2 = sData;
                                    sData = string.Concat(new object[] { obj2, "http://", this.string_0, ":", this.int_1, "/view100?camera=", i, "|" });
                                }
                                sData = sData.Trim(new char[] { '|' });
                                this.SendHeader(sHttpVersion, string.Empty, sData.Length, " 200 OK", ref socket_0);
                                this.SendToBrowser(sData, ref socket_0);
                            }
                            else
                            {
                                int result = -1;
                                if ((int.TryParse(s, out result) && (result >= 0)) && (result < this.int_0))
                                {
                                    if (ptzCommand == string.Empty)
                                    {
                                        if (this.ClientRequestCurrentImage != null)
                                        {
                                            this.ClientRequestCurrentImage(result);
                                        }
                                        MemoryStream stream = new MemoryStream();
                                        Bitmap bitmap = (Bitmap) CurrentFrames[result.ToString()];
                                        if (bitmap != null)
                                        {
                                            bitmap.Save(stream, ImageFormat.Jpeg);
                                            byte[] buffer2 = new byte[stream.Length];
                                            stream.Position = 0L;
                                            stream.Read(buffer2, 0, (int) stream.Length);
                                            this.SendHeader(sHttpVersion, "image/jpeg", (int) stream.Length, " 200 OK", ref socket_0);
                                            this.SendToBrowser(buffer2, ref socket_0);
                                        }
                                    }
                                    else if (this.ClientSendPTZCommand != null)
                                    {
                                        this.ClientSendPTZCommand(ptzCommand);
                                    }
                                }
                            }
                        }
                        catch (SocketException exception)
                        {
                            if (this.SocketErrorEvent != null)
                            {
                                this.SocketErrorEvent("Error while send data to client: " + exception.Message);
                            }
                        }
                        socket_0.Close();
                        socket_0 = null;
                    }
                    continue;
                }
                catch (Exception exception2)
                {
                    if (this.SocketErrorEvent != null)
                    {
                        this.SocketErrorEvent("Error while accept connection: " + exception2.Message);
                    }
                    continue;
                }
            }
        }

        public int CameraCount
        {
            get
            {
                return this.int_0;
            }
            set
            {
                this.int_0 = value;
            }
        }

        public bool Running
        {
            get
            {
                if (this.thread_0 != null)
                {
                    if (!this.thread_0.Join(0))
                    {
                        return true;
                    }
                    this.method_0();
                }
                return false;
            }
        }

        public string ServerIP
        {
            get
            {
                return this.string_0;
            }
            set
            {
                this.string_0 = value;
            }
        }

        public int ServerPort
        {
            get
            {
                return this.int_1;
            }
            set
            {
                this.int_1 = value;
            }
        }
    }
}

